package com.bluemartini.jmx;

import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import com.bluemartini.core.JNDIUtil;
import com.bluemartini.dna.BMException;
import com.bluemartini.dna.BMLog;
import com.bluemartini.server.BMAppServer;

/**
 * This class accesses JMX MBeanServer to provide generic API whatever the application server.</br>
 * It ensures MBeanServer is instantiated only once.
 * 
 * @author Yannick Robin
 *
 */
public class BMMBeanServer {

	public static final String MBEAN_DOMAIN_NAME = "BlueMartini";
	private static MBeanServer mbs_;

	private static synchronized MBeanServer getMBeanServer() throws BMException
	{
		if (mbs_ == null)
		{
			//TODO Use ManagementFactory for JMX API 1.2 (Since JDK 1.5)
			//mbs = ManagementFactory.getPlatformMBeanServer();
			BMAppServer appserver = BMAppServer.getAppServer();
			if (appserver.getType() == BMAppServer.TYPE_WEBLOGIC)
				mbs_ = getWebLogicMBeanServer();
			else
				mbs_ = getWebSphereMBeanServer();
			System.out.println("BM JMX: BMMBeanServer initialized");
			BMLog.log(BMLog.COMPONENT_SYSTEM, 1, "[BMMBeanServer.getMBeanServer] BMMBeanServer initialized");			
		}
		
		return mbs_;
	}
	
	//TODO Specific to third-party package
	private static MBeanServer getWebLogicMBeanServer() throws BMException
	{
		MBeanServer mbs;
		BMAppServer appserver = BMAppServer.getAppServer();
		String url = appserver.getJNDIURL(null, null);
		
		JNDIUtil jndiUtil = appserver.getJNDIUtil(url);
		InitialContext ctx;
		try {
			ctx = jndiUtil.getInitialContext();
			//Replace weblogic.management.server by java:comp/env/jmx/runtime for WLS 9.2??
			mbs = (MBeanServer)ctx.lookup("weblogic.management.server");				
		} catch (NamingException e) {
			throw new BMException("JNDI_INITIALIZATION_FAILED", e, null);
		}
		return mbs;
	}
	
	/**
	 * Not supported
	 * @return
	 * @throws BMException
	 */
	private static MBeanServer getWebSphereMBeanServer() throws BMException
	{
		throw new BMException("BM JMX is not supported for WebSphere");
	}
	
	/**
	 * Register MBean
	 * 
	 * @param objectName
	 * @param mbean
	 * @throws BMException
	 * @see javax.management.MBeanServer.registerMBean
	 */
	public static void registerMBean(String objectName, Object mbean) throws BMException
	{
		ObjectName oname;
		try {
			oname = new ObjectName(objectName);
		} catch (MalformedObjectNameException e) {
			throw new BMException("OBJECT_NAME_CREATION_FAILED", e, null);
		}
		
		MBeanServer mbs = getMBeanServer();
        try {
        	if (!mbs.isRegistered(oname))
        		mbs.registerMBean(mbean, oname);
		} catch (MBeanRegistrationException e) {
			throw new BMException("MBEAN_REGISTRATION_FAILED", e, null);
		} catch (NotCompliantMBeanException e) {
			throw new BMException("MBEAN_REGISTRATION_FAILED", e, null);
		} catch (InstanceAlreadyExistsException e) {
			throw new BMException("MBEAN_REGISTRATION_FAILED", e, null);
		}
	}
}
